<%-- 
    Document   : index
    Created on : Oct 28, 2012, 1:08:16 PM
    Author     : Gregory Scott (gptscott@gmail.com)
--%>
<%
    /* JSP defaults for latitude, longitude, etc. */
    double DEFAULT_IMAGE_LATITUDE = 51.510836; // NB latitude is North-South
    double DEFAULT_IMAGE_LONGITUDE = -0.244467;
    double DEFAULT_PHYS_IMAGE_WIDTH = 100; // in metres
    double DEFAULT_PHYS_IMAGE_HEIGHT = 100;
    double DEFAULT_PIX_IMAGE_WIDTH = 300;
    double DEFAULT_PIX_IMAGE_HEIGHT = 300;
    String DEFAULT_IMAGE_FILENAME = "image.png";

    double image_latitude = DEFAULT_IMAGE_LATITUDE;
    double image_longitude = DEFAULT_IMAGE_LONGITUDE;
    double phys_image_width = DEFAULT_PHYS_IMAGE_WIDTH;
    double phys_image_height = DEFAULT_PHYS_IMAGE_HEIGHT;

    double pix_image_width = DEFAULT_PIX_IMAGE_WIDTH;
    double pix_image_height = DEFAULT_PIX_IMAGE_HEIGHT;
    String image_filename = DEFAULT_IMAGE_FILENAME;

    /* Current hard coded converstion params for degrees latitude/longitude to metres */
    double lat_degree_to_metres = 111248.23835493479; // NB latitude is North-South
    double long_degree_to_metres = 70197.65060613726;

    /* Process any parameters passed to the JSP */
    if (request.getParameter("imagelatitude") != null) {
        try {
            image_latitude = Double.parseDouble(request.getParameter("imagelatitude"));
        } catch (NumberFormatException nfe) {
            image_latitude = DEFAULT_IMAGE_LATITUDE;
        }
    }
    if (request.getParameter("imagelongitude") != null) {
        try {
            image_longitude = Double.parseDouble(request.getParameter("imagelongitude"));
        } catch (NumberFormatException nfe) {
            image_longitude = DEFAULT_IMAGE_LATITUDE;
        }
    }
    if (request.getParameter("physimagewidth") != null) {
        try {
            phys_image_width = Double.parseDouble(request.getParameter("physimagewidth"));
        } catch (NumberFormatException nfe) {
            phys_image_width = DEFAULT_PHYS_IMAGE_WIDTH;
        }
    }
    if (request.getParameter("physimageheight") != null) {
        try {
            phys_image_height = Double.parseDouble(request.getParameter("physimageheight"));
        } catch (NumberFormatException nfe) {
            phys_image_width = DEFAULT_PHYS_IMAGE_HEIGHT;
        }
    }
    if (request.getParameter("imagefilename") != null) {
        image_filename = request.getParameter("imagefilename");
    }
    if (request.getParameter("piximagewidth") != null) {
        try {
            pix_image_width = Double.parseDouble(request.getParameter("piximagewidth"));
        } catch (NumberFormatException nfe) {
            pix_image_width = DEFAULT_PIX_IMAGE_WIDTH;
        }
    }
    if (request.getParameter("piximageheight") != null) {
        try {
            pix_image_height = Double.parseDouble(request.getParameter("piximageheight"));
        } catch (NumberFormatException nfe) {
            pix_image_width = DEFAULT_PIX_IMAGE_HEIGHT;
        }
    }

    double target_accuracy = Math.round(pix_image_width / phys_image_width) * 2;

%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>CrowdPix - Geospatial Crowd-sourced Display</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style>
            body {
                margin: 2em;
                font-family: Arial, sans-serif;
                font-size: 1em;
                color: #353535;
            }

            input {
                font-size: 1.0em;
                color: #9c0042;
            }

            button {
                font-family: Arial, sans-serif;
                font-weight: bold;
                font-size: 2em;

            }
            h1 {
                font-size: 2em;
            }

            h2 {
                font-size: 1.25em;
            }

            #status {
                display: inline;
            }

            #result {
                font-size: 0.75em;

            }

            #result .coordinates, #result .pix {
                font-color: #333333;
                display: block;
            }

            #result .accuracy {
                color: #333333;
            }


        </style>
        <script language="javascript">
            
            // CONSTANTS FOR HOW MANY METRES IN A LONG/LAT
            var lat_degree_to_metres = <%= lat_degree_to_metres%>; // NB latitude is North-South
            var long_degree_to_metres = <%= long_degree_to_metres%>; 
            
            // INVERSE OF THESE
            var lat_metre_to_degrees =  1 / lat_degree_to_metres;
            var long_metre_to_degrees = 1 / long_degree_to_metres;
            
            // THE CENTRE OF OUR IMAGE IN LAT/LONG
            var image_centre_lat = <%= image_latitude%>; // 51.510836; //51.51531004441019; // 51.51097870000202;
            var image_centre_long = <%= image_longitude%>; //-0.244467; //-0.24305396148826397; //-0.24437122999442426;
            
            // THE SIZE OF OUR IMAGE IN METRES
            var image_width = <%= phys_image_width%>;
            var image_height = <%= phys_image_height%>;
            
            // THE SIZE OF OUR IMAGE IN PIXELS
            var image_px_width = <%= pix_image_width%>;
            var image_px_height = <%= pix_image_height%>;
            
            // THE COORDINATES MARKING 'BOTTOM LEFT' AND 'TOP RIGHT' OF
            // THE IMAGE IN PHYSICAL SPACE (LONG/LAT)
            var x1 = image_centre_long - ((image_width / 2) * long_metre_to_degrees);
            var y1 = image_centre_lat - ((image_height / 2) * lat_metre_to_degrees);
            var x2 = image_centre_long + ((image_width / 2) * long_metre_to_degrees);
            var y2 = image_centre_lat + ((image_height / 2) * lat_metre_to_degrees);
           
            // LOAD THE IMAGE AND GET A 2D ARRAY REPRESENTING ITS PIXEL VALUES
            // NOTE SIZE OF DIV (HIDDEN) NEEDS TO BE SIZE OF IMAGE
            var imageData;
            var context;
            image = new Image();
            image.onerror = function() {
                document.getElementById( 'status' ).innerHTML = 'error';
            }    
            image.onload = function() {
                document.getElementById( 'status' ).innerHTML = 'loading..';
                context = document.getElementById('canvas').getContext('2d');
                document.getElementById('canvas').style.visibility="hidden";
                context.drawImage(image, 0, 0);
                imageData = context.getImageData(0, 0, image_px_width, image_px_height); 
            }
            image.src = "<%= image_filename%>";
            
            // VARIABLES TO STORE LOCATION AND ACCURACY
            var latitude, longitude, accuracy;

            function setGeolocation() {
                document.getElementById( 'status' ).innerHTML = 'fetching location..';
                    
                var geolocation = window.navigator.geolocation.watchPosition( 

                function ( position ) {

                    latitude = position.coords.latitude;
                    longitude = position.coords.longitude;
                    accuracy = position.coords.accuracy;

                    //latitude += Math.random() * ( 10 * lat_metre_to_degrees);
                    //longitude += Math.random() * ( 10 * long_metre_to_degrees);
                    
                    // write accuracy
                    document.getElementById( 'accuracy' ).innerHTML = accuracy;
                    document.getElementById( 'status' ).innerHTML = 'okay..';
                    
                    // write to the page the coordinates and accuracy
                    document.getElementById( 'result' ).innerHTML += 
                        '<span class="coordinates">Latitude: ' + latitude + ', '
                        + 'longitude ' + longitude + ', '
                        + '</span><span class="accuracy">Accuracy: ' + accuracy + 'metres</span>';
                       
                       
                    // calculate the pixel coordinates
                    pix_x = Math.round(
                    image_px_width * ( (longitude - x1) / (x2-x1)  )
                );// + image_px_width / 2;
                        
                    pix_y = Math.round (
                    image_px_height * ( ( latitude - y1 ) / (y2-y1) )
                );// + image_px_height / 2;
                    
                    // print reference coords
                    // document.getElementById( 'result' ).innerHTML += 
                    //   '<tt>x1,y1: ' + x1 + ', ' + y1 
                    //    + ' x2,y2: ' + x2 + ', ' + y2;
                       
                       
                       
                    // output pixel coordinates
                    document.getElementById( 'result' ).innerHTML +=
                        '<span class="pix">Giant image pixel x,y: ' + pix_x + ',' + pix_y + '</span> ' 
                    
                    
                    // if calculated to be in range, look up the pixel and set
                    // the background colour to it
                    if(pix_x >= 0 && pix_x <= image_px_width &&
                        pix_y >= 0 && pix_y <= image_px_height) {
                            
                        //document.getElementById( 'result' ).innerHTML += 'colour: ' + getPixel(imageData, pix_x, pix_y);
                            
                        document.body.style.background=getPixel(imageData,pix_x,pix_y);
                            
                    }
                    else {
                        document.getElementById( 'status' ).innerHTML = 'okay...but you are not standing in the image!';
                    }
                    
                },
                function handleError(error) { /*error*/
                    showError(error, document.getElementById('status'));
                },
                {   maximumAge: 15000, 
                    timeout: 15000,
                    enableHighAccuracy: true
                }  
            );

                //    window.setTimeout( function () {
                //        window.navigator.geolocation.clearWatch( geolocation ) 
                //    }, 
                //    5000 //stop checking after 5 seconds
                //);
            }

            //window.setTimeout( function () {
            //    setGeolocation();
            //}, 
            //15000 //check every 5 seconds
            //);
            
            function getPixel(imageData, x, y) {
                var pixel = context.getImageData(x, y, 1, 1);
                var rgb = pixel.data;
                return "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";
            }
                
            function getPixel2(imageData, x, y) {
                var r, g, b, a, offset = x * 4 + y * 4 * imageData.width;
                r = imageData.data[offset];
                g = imageData.data[offset + 1];
                b = imageData.data[offset + 2];
                a = imageData.data[offset + 3];
                return "rgba(" + r + "," + g + "," + b + "," + a + ")";
            }

    
            function showError(error, x)
            {
               
                x.innerHTML='error.';
                switch(error.code) 
                {
                    case error.PERMISSION_DENIED:
                        x.innerHTML="User denied the request for Geolocation - make sure you switch on location services and say yes to any pop-ups"
                        break;
                    case error.POSITION_UNAVAILABLE:
                        x.innerHTML="Location information is unavailable - make sure you switch on location services"
                        break;
                    case error.TIMEOUT:
                        x.innerHTML="The request to get user location timed out - try waiting for 10 seconds more, or click on Go!"
                        break;
                    case error.UNKNOWN_ERROR:
                        x.innerHTML="Sorry, an unknown error occurred. Probably your device or browser doesn't support what we're trying to do"
                        break;
                }
            }
         
        </script>
    </head>
    <body onclick="setGeolocation();" onload="setGeolocation();">
        <h1>CrowdPix - Geospatial Crowd-sourced Display by <a href="mailto:gptscott@gmail.com">Greg</a></h1>
        <h2>Come again?</h2>
        <p>If it works, the background of this page on your device will, based on your geospatial location, change colour 
            to form part of a giant <a href="<%= image_filename%>">image</a> stretched across physical space.</p>
        <p>The colour of your display will change to match the point within the image where you are standing. If you are in a crowd, and you are standing where the image should appear (you should be otherwise this won't work), if enough of you, spread about, are all looking at this, your devices will together light up the giant image. 

        <h2>Where on Earth is this giant image?</h2>
        <p>This has been specified by someone else (by parameters passed to this page, if you're curious). It is centred at 
            <em><%= image_latitude%> degrees latitude and <%= image_longitude%> longitude</em>, and is <em>
                <%= phys_image_width%> x <%= phys_image_height%> metres in size</em>. If you're no-where near that location, you can probably do something else.
        <h2>How do I make it go?</h2>
        <p>If things are going well, you shouldn't need to do a thing. Your location should be updated every now and again, too, depending on your phone and if you move. But pressing Go might work and, on some browsers, just click anywhere on the page.
        <p>Your current status is: <em><span id="status">please wait...</span></em>. Try pressing Go any time to refresh, or if you move, or if your location is too inaccurate and you want to try again.<br/>
        <p><a href="javascript: setGeolocation();">Go!</a>

        <h2>What do you mean by location accuracy?</h2>
        <p>This is how accurately your phone will tell us where you are. It depends on your phone, what kind of location you're in, and probably lots of other things. Your current accuracy as far as we can tell is <em><span id="accuracy">(please wait)</span> metres</em>. For this  to work reasonably well, so your phone is displaying the pixel (i.e. colour) it should to fit in the picture, your accuracy needs to be about <em><%= target_accuracy%> metres</em>.

        <h2>Where am I right now? Where abouts am I in the <A href="<%= image_filename%>">image</a>?</h2>
        <p>Your location (in physical space) and where you are in the image (which we work out) will be logged in the space below every time we can work it out. 
        <div id="result"></div>

        <!-- offscreen canvas -->
    <canvas id="canvas" width="<%= pix_image_width%>" height="<%= pix_image_height%>"></canvas>

</body>
</html>
